﻿using DatabaseTransfer.Connections;
using DatabaseTransfer.Databases;
using DatabaseTransfer.Factories;
using DatabaseTransfer.Interfaces;
using DatabaseTransfer.Logs;
using DatabaseTransfer.Tables;
using log4net;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DatabaseTransfer.Forms
{
    public partial class TableView : Form
    {
        private static ILog logger = LogFactory.GetLogger(typeof(TableView));

        private DatabaseConnector srcConnector;
        
        private DatabaseConnector destConnecter;

        public TableView(DatabaseConnector srcConnector, DatabaseConnector destConnecter)
        {
            InitializeComponent();

            this.srcConnector = srcConnector;
            this.destConnecter = destConnecter;

            SetupTableList();
        }

        private void SetupTableList()
        {
            SetupSourceList();
            SetupDestinationList();
        }

        private void SetupDestinationList()
        {
            new Thread(new ThreadStart(() =>
            {
                AbstractDatabase destDb = DatabaseFactory.GetDatabase(destConnecter);
                List<Table> tables = destDb.GetAvailableTables();

                if (tables == null)
                {
                    logger.Warn("Was unable to find tables in the destination database");
                    return;
                }

                if (this.destTables.InvokeRequired)
                {
                    this.Invoke((MethodInvoker)delegate { this.destTables.DataSource = tables; });
                }
                else
                {
                    this.destTables.DataSource = tables;
                }

            })).Start();
        }

        private void SetupSourceList()
        {
            new Thread(new ThreadStart(() =>
            {
                AbstractDatabase srcDb = DatabaseFactory.GetDatabase(srcConnector);
                List<Table> tables = srcDb.GetAvailableTables();

                if (tables == null)
                {
                    logger.Warn("Was unable to find tables in source database.");
                    return;
                }

                if (this.srcTables.InvokeRequired)
                {
                    this.Invoke((MethodInvoker)delegate { this.srcTables.DataSource = tables; });
                }
                else
                {
                    srcTables.DataSource = tables;
                }

            })).Start();
        }

        private void continueBtn_Click(object sender, EventArgs e)
        {
            Table srcTable = (Table)srcTables.SelectedItem;
            Table destTable = (Table)destTables.SelectedItem;

            if (srcTable == null)
            {
                MessageBox.Show("Source table wasn't selected");
                logger.Warn("No source table selected");
                return;
            }

            if (destTable == null)
            {
                MessageBox.Show("Destination table wasn't selected");
                logger.Warn("No detination table selected");
                return;
            }

            srcTable.Database = DatabaseFactory.GetDatabase(srcConnector);
            destTable.Database = DatabaseFactory.GetDatabase(destConnecter);

            ColumnMatcher matcher = new ColumnMatcher(srcTable, destTable);
            matcher.Show();
            matcher.SetupColumns();
        }

        private void closeBtn_Click(object sender, EventArgs e)
        {
            this.Dispose();
        }

    }
}
